home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 1 / BBS in a box - Trilogy I.iso / Files / Publish / J-L / lpr / lpr source / settings.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-18  |  12.0 KB  |  470 lines  |  [TEXT/MPS ]

  1. #if !defined(USEDUMP)
  2.     #include "lprlib.h"
  3.     #include "lprdef.h"
  4.     #include "lprfuncs.h"
  5. #else
  6.     #pragma load "lprDumpFile"
  7. #endif
  8.  
  9. typedef struct {
  10.     unsigned char * name;
  11.     unsigned char type;
  12.     unsigned char size;
  13.     unsigned char * valptr;
  14.     unsigned char * dvalptr;
  15.     unsigned char * description;
  16.     } keyinfo;
  17.  
  18. extern unsigned char tcpinitok;
  19. extern settings_list ds, cs, fs;
  20. extern unsigned char vmpass[9];        /* VM password */
  21. extern unsigned long passtime;        /* time password last stored */
  22.  
  23. static keyinfo keytab[] = {
  24.     {"class", 's', 2, fs.vmclass, ds.vmclass, "VM print class"},
  25.     {"copies", 'u', 1, &fs.copycnt, &ds.copycnt, "Copy count"},
  26.     {"debug", 'u', 1, &fs.dblevel, &ds.dblevel, "Debug level"},
  27.     {"duplex", 'b', 1, &fs.duplex, &ds.duplex, "Duplex formatting"},
  28.     {"form", 's', 9, fs.vmform, ds.vmform, "VM form type"},
  29.     {"format", 'u', 1, &fs.fmttype, &ds.fmttype, "Formatting type (1-3)"},
  30.     {"hdrclass", 's', 64, fs.hdrclass, ds.hdrclass, "Header classification"},
  31.     {"hdrid", 's', 64, fs.hdrid, ds.hdrid, "Header user identification"},
  32.     {"header", 'b', 1, &fs.hdrflag, &ds.hdrflag, "Generate header page (0 or 1)"},
  33.     {"host", 's', 128, fs.hostname, ds.hostname, "Host name"},
  34.     {"indent", 'u', 1, &fs.findent, &ds.findent, "Indent amount"},
  35.     {"noff", 'b', 1, &fs.noff, &ds.noff, "Suppress form feed between files"},
  36.     {"jobname", 's', 64, fs.jobname, ds.jobname, "Header job name"},
  37.     {"myhost", 's', 64, fs.orghost, ds.orghost, "My host's name"},
  38.     {"newprot", 'b', 1, &fs.newprot, &ds.newprot, "New lpr protocol"},
  39.     {"pascal", 'b', 1, &fs.pascalflag, &ds.pascalflag, "Pascal formatting (0 or 1)"},
  40.     {"pgsize", 'u', 1, &fs.fpgsize, &ds.fpgsize, "Page size (line count)"},
  41.     {"printer", 's', 64, fs.printer, ds.printer, "Printer name"},
  42.     {"retries", 'u', 1, &fs.retries, &ds.retries, "Network retry count"},
  43.     {"split", 'b', 1, &fs.splitflag, &ds.splitflag, "Split long lines (0 or 1)"},
  44.     {"tabsize", 'u', 1, &fs.ftabsize, &ds.ftabsize, "Tab column spacing"},
  45.     {"timeout", 'u', 1, &fs.timeout, &ds.timeout, "Network timeout interval"},
  46.     {"title", 's', 64, fs.fmttitle, ds.fmttitle, "Title line"},
  47.     {"topmrg", 'u', 1, &fs.ftop, &ds.ftop, "Top margin"},
  48.     {"userid", 's', 9, fs.vmuser, ds.vmuser, "VM userid"},
  49.     {"username", 's', 64, fs.orguser, ds.orguser, "User name"},
  50.     {"vm", 'b', 1, &fs.vmflag, &ds.vmflag, "VM printer (0 or 1)"},
  51.     {"width", 'u', 1, &fs.fwidth, &ds.fwidth, "Line width"},
  52.     {0, 0, 0, 0, 0, 0} };        /* marks end of list */
  53.  
  54. extern struct Point sfppoint, sfgpoint;
  55. unsigned char setmsg1[256];    
  56. unsigned char setmsg2[256];    
  57. static unsigned char s_fName[64] = "";    /* last good settings filename */
  58.  
  59. OSErr init_settings(void)
  60. {
  61. short appmsg, appcount;
  62. AppFile appinfo;
  63.  
  64. /* initial file settings are defaults */
  65. fs = cs;
  66.  
  67. /* attempt to get a file id for reading new settings */
  68.  
  69. /* first try file passed by the Finder (or whomever) */
  70. CountAppFiles(&appmsg, &appcount);
  71. if ((appmsg == appOpen) && (appcount > 0)) {
  72.     GetAppFiles(1, &appinfo);
  73.     p2cstr(&appinfo.fName);
  74.     if (appinfo.fType == 'lprp')
  75.         if (0 == get_settings(&appinfo.fName, appinfo.vRefNum, 1)) return(0);
  76.     }
  77.  
  78. /* Next, try a standard get file dialog */
  79. if (0 == read_settings(1)) return(0);
  80. return(1);
  81. }
  82.  
  83. short read_settings(initflg)
  84. unsigned char initflg;
  85. {
  86. Point where;
  87. FileFilterProcPtr fileFilter;
  88. DlgHookProcPtr dlgHook;
  89. short numTypes;
  90. SFTypeList typeList;
  91. SFReply reply;
  92. pascal Boolean (*filterProc) ();
  93.  
  94. where = sfgpoint;
  95. fileFilter = 0;
  96. dlgHook = 0;
  97. numTypes = 1;
  98. typeList[0] = 'lprp';
  99. dlgHook = 0;
  100. filterProc = SF_Filter;
  101. SFPGetFile(where, "\pDefine remote printer from:", fileFilter,
  102.              numTypes, typeList, dlgHook, &reply, getDlgID,
  103.              (ModalFilterProcPtr)filterProc);
  104. if (reply.good == 0) return(8);
  105. p2cstr(&reply.fName);
  106. return(get_settings(&reply.fName, reply.vRefNum, initflg));
  107. }
  108.  
  109. short get_settings(fname, vnum, initflg)
  110. unsigned char * fname;
  111. short vnum;
  112. unsigned char initflg;
  113. {
  114.                             /* state table for reading definition file */
  115. static unsigned unsigned char statetab[] =
  116. /*                                0        1        2        3        4        5        6    */
  117. /*                               space   char     '='     '#'      CR    other    EOF    */
  118. /* 0: before name field    */ {    0,        2,        8,        1,        0,        8,        0,
  119. /* 1: comment line        */        1,        1,        1,        1,        0,        1,        0,
  120. /* 2: reading name        */        3,        2,        4,        8,        8,        8,        8,
  121. /* 3: between name and =*/        3,        8,        4,        8,        8,        8,        8,
  122. /* 4: between = and val    */        4,        5,        8,        8,        8,        8,        8,
  123. /* 5: reading value        */        6,        5,        8,        7,        0,        8,        0,
  124. /* 6: after value        */        6,        8,        8,        7,        0,        8,        0,
  125. /* 7: end comment        */        7,        7,        7,        7,        0,        7,        0 };
  126. /* 8: error                */
  127.  
  128. short fnum;
  129. OSErr rc;
  130. long filesize, l, readcount;
  131. unsigned char * filedata;
  132. unsigned char * nameptr, * valueptr;
  133. short oldstate, state, charindex;
  134. short linenum, namelen, valuelen;
  135.  
  136. nameptr = valueptr = 0;            /* just to avoid warning messages */
  137. namelen = valuelen = 0;
  138.  
  139.                     /* set default volume to initial settings location */
  140. if (initflg) SetVol(0L, vnum);    
  141.                     /* prepare first part of error messages */
  142. sprintf(setmsg1, "Error reading definition file %s", fname);
  143.                     /* read definition file into buffer */
  144. rc = fsrdopen(fname, vnum, &fnum);
  145. if (rc != 0) {
  146.     sprintf(setmsg2, "Error %d opening file", rc);
  147.     seterr();
  148.     return(rc);
  149.     }
  150. rc = GetEOF(fnum, &filesize);    /* get file size */
  151. if (rc != 0) {
  152.     FSClose(fnum);
  153.     sprintf(setmsg2, "Error %d getting file size", rc);
  154.     seterr();
  155.     return(rc);
  156.     }
  157. filedata = (unsigned char *)NewPtr(filesize+1);    /* allocate buffer */
  158.                             /* extra byte for null termination */
  159. if (filedata == 0L) {
  160.     FSClose(fnum);
  161.     sprintf(setmsg2, "Not enough storage (%ld bytes) for file", filesize);
  162.     seterr();
  163.     return(rc);
  164.     }
  165. readcount = filesize;            /* read file data */
  166. rc = FSRead(fnum, &readcount, filedata);
  167. FSClose(fnum);                    /* close file */
  168. if ((rc != 0) || (readcount != filesize)) {
  169.     DisposPtr(filedata);
  170.     if (rc == 0) rc = 4;
  171.     sprintf(setmsg2, "Error %d reading file contents", rc);
  172.     seterr();
  173.     return(rc);
  174.     }
  175.  
  176. state = 0;
  177. linenum = 1;
  178. fs = ds;            /* start with default settings */
  179. for (l=0; l <= filesize; l++) {
  180.     if (l < filesize)
  181.         charindex = chrval(filedata[l]);
  182.     else charindex = 6;        /* EOF */
  183.     oldstate = state;
  184.     state = statetab[oldstate*7 + charindex]; 
  185.     if (state == 8) break;
  186.     if ((oldstate >= 5) && (state == 0)) {
  187.         rc = setval(nameptr, namelen, valueptr, valuelen);
  188.         if (rc != 0) {
  189.             state = 8;
  190.             break;
  191.             }
  192.         }
  193.     if (charindex == 4) linenum++;
  194.     if (charindex == 1)
  195.         switch(state) {
  196.                 case 2:
  197.                         if (oldstate == 2) namelen++;
  198.                         else {
  199.                             nameptr = filedata+l;
  200.                             namelen = 1;
  201.                             }
  202.                         break;
  203.                 case 5:
  204.                         if (oldstate == 5) valuelen++;
  205.                         else {
  206.                             valueptr = filedata+l;
  207.                             valuelen = 1;
  208.                             }
  209.                         break;
  210.                 default:
  211.                         break;
  212.                 }
  213.     }
  214. DisposPtr(filedata);
  215. /* if userid has changed, reset password */
  216. if (strcmp(cs.vmuser, fs.vmuser) != 0) {
  217.     memset(vmpass, 0, 9);
  218.     passtime = 0;
  219.     }
  220. cs = fs;                /* copy file values to current settings */
  221.  
  222. if (state == 8) {        /* error state */
  223.     sprintf(setmsg2, "Syntax or keyword error on line %d", linenum);
  224.     seterr();
  225.     return(8);
  226.     }
  227. else {
  228.     memcpy(s_fName, fname, 64);        /* save name of good file */
  229.     return(0);
  230.     }
  231. }
  232.  
  233. void seterr(void)
  234. {
  235. pascal Boolean (*filterProc) ();
  236.  
  237. filterProc = DlgFilter;        /* for error alert */
  238. c2pstr(setmsg1);
  239. c2pstr(setmsg2);
  240. ParamText(setmsg1, setmsg2, "\p", "\p");
  241. p2cstr(setmsg1);
  242. p2cstr(setmsg2);
  243. putln(setmsg1);
  244. putln(setmsg2);
  245. StopAlert(261, (ModalFilterProcPtr)filterProc);
  246. ParamText("\p", "\p", "\p", "\p");
  247. }
  248.  
  249. short chrval(chr)
  250. unsigned char chr;
  251. {
  252. register unsigned char c;
  253.  
  254. c = chr & 0x7f;
  255. switch (c) {
  256.     case '=':
  257.             return(2);
  258.             break;
  259.     case '#':
  260.             return(3);
  261.             break;
  262.     case 0x0d:
  263.             return(4);
  264.             break;
  265.     default:
  266.             if (isspace(c)) return(0);
  267.             else if (isprint(c)) return(1);
  268.                     else return(5);
  269.             break;
  270.     }
  271. }
  272.  
  273. short setval(nameptr, namelen, valueptr, valuelen)
  274. unsigned char * nameptr, * valueptr;
  275. short namelen, valuelen;
  276. {
  277. register short i;
  278. keyinfo * k;
  279. unsigned char namesave, valuesave;
  280.  
  281. for (i=0; i < namelen; i++)
  282.     nameptr[i] = tolower(nameptr[i]);
  283. namesave = nameptr[namelen];
  284. nameptr[namelen] = 0;
  285. valueptr[valuelen] = 0;
  286. k = keytab;
  287. while (k->size > 0) {
  288.     if (strcmp(nameptr, k->name) == 0) break;
  289.     k++;
  290.     }
  291. nameptr[namelen] = namesave;
  292. if (k->size == 0) return(1);
  293. switch(k->type) {
  294.     case 'b':            /* binary flag */
  295.         for (i=0; i < valuelen; i++)
  296.             if (!isdigit(valueptr[i])) return(3);
  297.         valuesave = valueptr[valuelen];
  298.         valueptr[valuelen] = 0;
  299.         i = atoi(valueptr);
  300.         valueptr[valuelen] = valuesave;
  301.         if ((i < 0) || (i > 1)) return(4);
  302.         *(k->valptr) = i;
  303.         break;
  304.     case 'u':            /* unsigned char */
  305.         for (i=0; i < valuelen; i++)
  306.             if (!isdigit(valueptr[i])) return(3);
  307.         valuesave = valueptr[valuelen];
  308.         valueptr[valuelen] = 0;
  309.         i = atoi(valueptr);
  310.         valueptr[valuelen] = valuesave;
  311.         if ((i < 0) || (i > 255)) return(4);
  312.         *(k->valptr) = i;
  313.         break;
  314.     case 'i':            /* integer */
  315.         for (i=0; i < valuelen; i++)
  316.             if (!isdigit(valueptr[i])) return(5);
  317.         valuesave = valueptr[valuelen];
  318.         valueptr[valuelen] = 0;
  319.         i = atoi(valueptr);
  320.         valueptr[valuelen] = valuesave;
  321.         *((short *)(k->valptr)) = i;
  322.         break;
  323.     case 's':            /* string */
  324.         if (valuelen > k->size - 1) return(6);
  325.         memset(k->valptr, 0, k->size);
  326.         memcpy(k->valptr, valueptr, valuelen);
  327.         break;
  328.     default:
  329.         return(2);
  330.         break;
  331.     }
  332. return(0);
  333. }
  334.  
  335. void write_settings(void)
  336. {
  337. Point where;
  338. DlgHookProcPtr dlgHook;
  339. SFReply reply;
  340. OSErr rc;
  341. short fnum;
  342. long count;
  343. unsigned char s[256];
  344. keyinfo * k;
  345. pascal Boolean (*filterProc) ();
  346.  
  347. where = sfppoint;
  348. dlgHook = 0;
  349. c2pstr(s_fName);
  350. filterProc = SF_Filter;
  351. SFPPutFile(where, "\pSave current settings as:",
  352.           s_fName, dlgHook, &reply, putDlgID,
  353.           (ModalFilterProcPtr)filterProc);
  354. p2cstr(s_fName);
  355. if (reply.good == 0) return;
  356. p2cstr(&reply.fName);
  357. memcpy(s_fName, &reply.fName, 64);        /* save filename */
  358. sprintf(setmsg1, "Error writing definition file %s", &reply.fName);
  359. c2pstr(&reply.fName);
  360. rc = FSDelete(&reply.fName, reply.vRefNum);    /* delete existing file */
  361. if ((rc != 0) && (rc != -43)) {        /* file not found is ok */
  362.     sprintf(setmsg2, "Error %d deleting  existing file", rc);
  363.     seterr();
  364.     return;
  365.     }
  366. rc = Create(&reply.fName, reply.vRefNum, 'lpra', 'lprp');
  367. if (rc != 0) {
  368.     sprintf(setmsg2, "Error %d creating new file", rc);
  369.     seterr();
  370.     return;
  371.     }
  372. rc = FSOpen(&reply.fName, reply.vRefNum, &fnum);
  373. if (rc != 0) {
  374.     sprintf(setmsg2, "Error %d opening new file", rc);
  375.     seterr();
  376.     return;
  377.     }
  378.                         /* save current values as file values */
  379. fs = cs;
  380.                         /* handle excluding VM userid */
  381.                         /* write each value */
  382. k = keytab;
  383. while (k->size != 0) {
  384.     s[0] = 0;
  385.     switch (k->type) {
  386.         case 'b':
  387.             if (*((unsigned char *)k->valptr) ==
  388.                 *((unsigned char *)k->dvalptr)) break;
  389.             sprintf(s, "%s=%d   #%s\015", k->name,
  390.                 *((unsigned char *)k->valptr), k->description);
  391.             break;
  392.         case 'u':
  393.             if (*((unsigned char *)k->valptr) == 0) break;
  394.             if (*((unsigned char *)k->valptr) ==
  395.                 *((unsigned char *)k->dvalptr)) break;
  396.             sprintf(s, "%s=%d   #%s\015", k->name,
  397.                 *((unsigned char *)k->valptr), k->description);
  398.             break;
  399.         case 'i':
  400.             if (*((short *)k->valptr) ==
  401.                 *((short *)k->dvalptr)) break;
  402.             sprintf(s, "%s=%d   #%s\015", k->name,
  403.                 *((short *)k->valptr), k->description);
  404.             break;
  405.         case 's':
  406.             if (strcmp(k->valptr, k->dvalptr) == 0) break;
  407.             if ((k->valptr)[0] == 0) break;
  408.             if ((unsigned char *)k->valptr == fs.vmuser)
  409.                 if (vmuserdlg()) break;
  410.             sprintf(s, "%s=%s   #%s\015", k->name,
  411.                     k->valptr, k->description);
  412.             break;
  413.         default:
  414.             break;
  415.         }
  416.     if (s[0] != 0) {
  417.         count = strlen(s);
  418.         rc = FSWrite(fnum, &count, s);
  419.         if (rc != 0) {
  420.             sprintf(setmsg2, "Error %d writing to file", rc);
  421.             seterr();
  422.             return;
  423.             }
  424.         }
  425.     k++;
  426.     }
  427. rc = FSClose(fnum);
  428. if (rc != 0) {
  429.     sprintf(setmsg2, "Error %d closing file", rc);
  430.     seterr();
  431.     }
  432. }
  433.  
  434. short new_settings(void)
  435. {
  436. return(fs != cs);
  437. }
  438.  
  439. OSErr fsrdopen(fname, vref, fref)    /* open file read-only */
  440. unsigned char * fname;
  441. short vref;
  442. short * fref;
  443. {
  444. IOParam pbi;
  445. OSErr rc;
  446.  
  447. /* initialize parameter block */
  448. memset(&pbi, 0, sizeof(IOParam));
  449.  
  450. pbi.ioNamePtr = (StringPtr)fname;
  451. pbi.ioVRefNum = vref;
  452. pbi.ioPermssn = fsRdPerm;
  453. c2pstr(fname);
  454. rc = PBOpen((ParmBlkPtr)&pbi, 0);
  455. *fref = pbi.ioRefNum;
  456. p2cstr(fname);
  457. return(rc);
  458. }
  459.  
  460. pascal Boolean SF_Filter(dlg, eventptr, itemptr)
  461. DialogPtr dlg;
  462. EventRecord * eventptr;
  463. short * itemptr;
  464. {
  465. #pragma unused(dlg, eventptr, itemptr)
  466.  
  467. /* if (tcpinitok) Stask(); */
  468. return(false);
  469. }
  470.